package com.tydic.trans.service.impl;

import com.tydic.trans.beans.Student;
import com.tydic.trans.mapper.StudentMapper;
import com.tydic.trans.service.TransactionService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

/**
 * @Author 714班
 */
@Service
public class TransactionSertviceImpl implements TransactionService {

    @Autowired
    private StudentMapper studentMapper;

    private Student student;

    public TransactionSertviceImpl() {
        this.student = new Student();
    }

    @Override
    public void demo1() {
        student.setId(1);
        student.setName("壹壹壹-update");
        student.setAge(18);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
        /**
         * 不加@Transactional，事物不会回滚
         */
    }

    @Transactional
    public void demo2() {
        student.setId(1);
        student.setName("贰贰贰-update");
        student.setAge(20);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
    }

    @Transactional
    public void demo3() {
        try {
            student.setId(1);
            student.setName("叁叁叁-update");
            student.setAge(22);
            int update = studentMapper.updateByPrimaryKeySelective(student);
            System.out.println("更新结果：" + update);
            //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
            int a = 10 / 0;
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    public void demo4() {
        try {
            student.setId(1);
            student.setName("肆肆肆-update");
            student.setAge(24);
            int update = studentMapper.updateByPrimaryKeySelective(student);
            System.out.println("更新结果：" + update);
            //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
            int a = 10 / 0;
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new RuntimeException("主动抛出一个RuntimeException异常");
        }
    }

    @Transactional
    public void demo5() throws IOException {
        try {
            student.setId(1);
            student.setName("伍伍伍-update");
            student.setAge(26);
            int update = studentMapper.updateByPrimaryKeySelective(student);
            System.out.println("更新结果：" + update);
            //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
            int a = 10 / 0;
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new IOException("主动抛出一个非RuntimeException异常");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void demo6() throws IOException {
        try {
            student.setId(1);
            student.setName("陆陆陆-update");
            student.setAge(28);
            int update = studentMapper.updateByPrimaryKeySelective(student);
            System.out.println("更新结果：" + update);
            //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
            int a = 10 / 0;
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new IOException("主动抛出一个非RuntimeException异常");
        }
    }

    public void demo7() {
        demo7Update();//不带事务的方法调用该类中带事务的方法，不会回滚
    }

    @Transactional
    public void demo7Update() {
        student.setId(1);
        student.setName("柒柒柒-update");
        student.setAge(30);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
    }

    @Transactional
    public void demo8() {
        demo8Update();//带事务的方法调用该类中不带事务的方法，不会回滚
    }

    public void demo8Update() {
        student.setId(1);
        student.setName("捌捌捌-update");
        student.setAge(32);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
    }

    @Transactional
    public void demo9() {
        demo9Update();
    }

    /**
     * Propagation.REQUIRED: 如果存在一个事务，则支持当前事务。如果没有事务则开启事务；
     * Propagation.REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在，则将这个存在的事务挂起。
     * spring中在一个拥有事务的方法A中调用另一个会挂起事务并创建新事务的方法B，如果使用this调用这个方法B，
     * 此时方法B抛出了一个异常，此时的方法B的事务会失效的。并不会回滚 （测试结果是会回滚）
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void demo9Update() {
        student.setId(1);
        student.setName("玖玖玖-update");
        student.setAge(34);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
    }

    public void demo10() {
        TransactionSertviceImpl proxy =(TransactionSertviceImpl) AopContext.currentProxy();
        proxy.demo10Update();
    }

    @Transactional
    public void demo10Update() {
        student.setId(1);
        student.setName("拾拾拾-update");
        student.setAge(36);
        int update = studentMapper.updateByPrimaryKeySelective(student);
        System.out.println("更新结果：" + update);
        //除数不能为0，所以此处会抛出一个运行时的异常，测试回滚
        int a = 10 / 0;
    }
}